<template>
  <div class="n-modal">
    <!-- 使用 AModal 组件实现模态框 -->
    <ElDialog v-bind="$attrs" v-model="open" @open="handleOpen" @close="handleClose" :destroy-on-close="true"
      :close-on-click-modal="false" :draggable="true" :fullscreen="fullScreen" :show-close="false"
      :body-class="`n-modal-body ${fullScreen ? '' : 'not-full-modal-body overflow-y-auto overflow-x-hidden'}`"
      align-center>

      <!-- 模态框标题 -->
      <template #header>
        <div class="modal-header">
          <div>
            {{ title }}
          </div>
          <ElSpace>

            <!-- 全屏切换按钮 -->
            <div v-if="showFullScreen === true" class="modal-header-btn cursor-pointer"
              @click="fullScreen = !fullScreen">
              <SvgIcon :icon="fullScreen ? 'material-symbols:fullscreen-exit' : 'material-symbols:fullscreen'"
                class="text-16px">
              </SvgIcon>
            </div>

            <div class="modal-header-btn cursor-pointer" @click="open = false">
              <SvgIcon icon="material-symbols:close-rounded" class="text-16px"></SvgIcon>
            </div>
          </ElSpace>
        </div>


      </template>
      <!-- 动态插入其他命名插槽 -->
      <template v-for="(_, name) in $slots" #[name]>
        <slot :name="name"></slot>
      </template>

      <!-- 如果 showFooter 为 false，则隐藏底部 -->
      <template #footer v-if="showFooter === false"></template>
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
import { reactify, useDraggable } from '@vueuse/core';
import { computed, CSSProperties, reactive, ref, watch, watchEffect } from 'vue';

const open = defineModel('open', {
  type: Boolean,
  default: false
})
// 定义组件 props
const props = defineProps({
  title: {
    type: String,
    default: ''
  },
  showFooter: {
    type: Boolean,
    default: true
  },
  showFullScreen: {
    type: Boolean,
    default: false
  },
  modalWidth: {
    type: String,
    default: "70%"
  },
  modalHeight: {
    type: String,
    default: "calc(80vh - 55px - 53px)"
  },
  backGroundColor: {
    type: String,
    default: "#fff"
  },
  showBodyBorder: {
    type: Boolean,
    default: false
  }
});

// 定义 emit
const emit = defineEmits(['update:modelValue', 'handleFullScreenChange'])

const handleOpen = () => {

  emit('update:modelValue', true)
}
const handleClose = () => {

  // 关闭时重置全屏状态
  if (fullScreen.value) {
    fullScreen.value = false;
  }
  emit('update:modelValue', false)
}
// 处理 visible 状态变化
const handleVisibleChange = (visible: boolean) => {
  if (!visible) {
    // 关闭时重置全屏状态
    if (fullScreen.value) {
      fullScreen.value = false;
    }
  }
  emit('update:modelValue', visible)
}

//#region 全屏相关
const fullScreen = ref(false);
watch(fullScreen, (val) => {
  Object.assign(dragModel, createDefaultModel())
  emit('handleFullScreenChange', val)
});
const isHovered = ref(false);
//#endregion

//#region 拖拽相关
const modalTitleRef = ref<HTMLElement>();
const { x, y, isDragging } = useDraggable(modalTitleRef);

// 创建默认拖拽模型
const createDefaultModel = () => {
  return {
    startX: 0,
    startY: 0,
    startedDrag: false,
    transformX: 0,
    transformY: 0,
    preTransformX: 0,
    preTransformY: 0,
    dragRect: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0
    }
  }
}
type DragModel = ReturnType<typeof createDefaultModel>;
const dragModel = reactive<DragModel>(createDefaultModel());

// 监听 x 和 y 的变化（拖拽位置）
watch([x, y], () => {
  //全屏状态不能拖动
  if (fullScreen.value === false && !dragModel.startedDrag && modalTitleRef.value) {
    dragModel.startX = x.value;
    dragModel.startY = y.value;
    const bodyRect = document.body.getBoundingClientRect();
    const titleRect = modalTitleRef.value.getBoundingClientRect();
    dragModel.dragRect.right = bodyRect.width - titleRect.width;
    dragModel.dragRect.bottom = bodyRect.height - titleRect.height;
    dragModel.preTransformX = dragModel.transformX;
    dragModel.preTransformY = dragModel.transformY;
  }
  dragModel.startedDrag = true;
});

// 监听是否停止拖拽
watch(isDragging, () => {
  if (!isDragging) {
    dragModel.startedDrag = false;
  }
});

// 实时更新拖拽偏移量
watchEffect(() => {
  if (dragModel.startedDrag) {
    dragModel.transformX =
      dragModel.preTransformX +
      Math.min(Math.max(dragModel.dragRect.left, x.value), dragModel.dragRect.right) -
      dragModel.startX;
    dragModel.transformY =
      dragModel.preTransformY +
      Math.min(Math.max(dragModel.dragRect.top, y.value), dragModel.dragRect.bottom) -
      dragModel.startY;
  }
});

// 计算样式偏移
const transformStyle = computed<CSSProperties>(() => {
  return {
    transform: `translate(${dragModel.transformX}px, ${dragModel.transformY}px)`,
  };
});
//#endregion
</script>

<style lang="scss">
.modal-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 16px;
}

.modal-header-btn {
  width: 22px;
  height: 22px;
  border: 3px solid transparent;
  border-radius: 3px;
  transition: background-color 0.3s ease;
  box-sizing: border-box;
  color: #8C8C8C;
  transition: 'all 0.3s ease'
}

.modal-header-btn:hover {
  background-color: #F0F0F0;
  color: #1D1D1D;
}

.not-full-modal-body {
  max-height: calc(100vh - 155px - 153px);
}

.n-modal-body {
  padding: 16px;
}
</style>
